import "./AvatarInput.scss";
import { Upload, Icon, Input, message } from "antd";
import { ReactComponent } from "../../class/ReactComponent";
import React from "react";
import { remote } from "electron";
import * as path from "path";
import { randInt } from "../../../common/function/numFunc";
import { randStr } from "../../../common/function/stringFunc";
import { UploadChangeParam } from "antd/lib/upload";
import { UploadFile } from "antd/lib/upload/interface";
import { copyImg } from "../../../common/function/fileFunc";

export namespace AvatarInput {
    export interface State extends ReactComponent.State {
        loading: boolean;
        imgURL: string;
    }
    export interface Props extends ReactComponent.Props {
        canMove?: (fileObj: UploadFile<any>) => boolean | string;
        uploadText?: string;
        limitSize?: number;
        accept?: string;
        onMoveOkay?: (pathname: string) => void;
        onChange?: (pathname: string) => void;
        value?: string;
    }
}

export class AvatarInput extends ReactComponent<AvatarInput.Props, AvatarInput.State> {
    public readonly state = {
        loading: false,
        imgURL: "",
    };
    public render() {
        return (
            <div className={this.getClsName("avatar-input-component")}>
                <Upload
                    name="avatar"
                    listType="picture-card"
                    showUploadList={false}
                    onChange={this.updateImgURL.bind(this)}
                    accept={this.props.accept || "image/*"}
                    customRequest={this.requestFunc.bind(this)}
                >{this.getImgElm()}</Upload>
                <Input
                    value={this.state.imgURL || ""}
                    onChange={(evt) => { this.updateImgURLByEvt(evt); }}
                    placeholder="请输入图片地址"
                />
            </div>
        );
    }
    public componentDidMount(): void {
        const props = this.props;
        this.setState({
            imgURL: props.value,
        });
    }
    public componentWillReceiveProps(nextProps: Readonly<AvatarInput.Props>, nextContext: any): void {
        if (this.state.imgURL !== nextProps.value) {
            this.setState({
                imgURL: nextProps.value,
            });
        }
    }

    protected getImgElm() {
        if (this.props.value) {
            return this.getImgElmByURL(this.props.value);
        }
        return this.getDefaultIcon();
    }
    protected getDefaultIcon() {
        return (
            <div className="avatar-input-default-icon avatar-input-img">
                <Icon type={this.state.loading ? "loading" : "plus"} />
                <div className="ant-upload-text">{this.props.uploadText || "上传"}</div>
            </div>
        );
    }
    protected getImgElmByURL(imgURL: string) {
        return (
            <div className="avatar-input-img avatar-input-url-img">
                <img src={imgURL} />
            </div>
        );
    }
    protected requestFunc() {
        return true;
    }
    protected updateImgURL(fileObj: UploadChangeParam<UploadFile<any>>) {
        const { file } = fileObj;
        const moveable = this.canMove(file);
        if (moveable === true) {
            this.moveFile(file);
        } else if (typeof moveable === "string") {
            message.error(moveable);
        }
    }
    protected canMove(fileObj: UploadFile<any>) {
        if (typeof this.props.canMove === "function") {
            return this.props.canMove(fileObj);
        }
        const limitSize = this.props.limitSize || 0;
        if (limitSize && (limitSize < fileObj.size)) {
            return `超过最大文件大小: ${limitSize}byte`;
        }
        return true;
    }
    protected moveFile(file: UploadFile<any>) {
        const fileName = randStr(randInt(10, 20)) + "@" + Date.now() + path.extname(file.name);
        const newFileName = path.join(
            path.dirname(
                remote.app.getAppPath()
            ).replace(/\\/g, "/"),
            "cover",
            fileName
        );
        const originFile = file.originFileObj as File;
        copyImg(originFile.path, newFileName).then((pathname) => {
            if (typeof this.props.onMoveOkay === "function") {
                this.props.onMoveOkay(pathname);
            }
            this.updateImgURLByURL(pathname);
        }).catch((err) => {
            message.error("保存时出错");
            console.error(err);
        });
    }
    protected updateImgURLByEvt(evt: React.ChangeEvent<HTMLInputElement>) {
        let inputVal = evt.target.value;
        if (inputVal) {
            inputVal = inputVal.trim();
            const isURLReg = /^(akaba:\/{3}|https?:\/{2})(\w[\w\-&%?#.\/:]+)/;
            const result = inputVal.match(isURLReg);
            const hasSlash = result.indexOf("\\") >= 0;
            if (result && !hasSlash) {
                this.updateImgURLByURL(inputVal);
                return;
            }
            if (hasSlash) {
                message.error("路径不能包含字符(\\)");
            }
            this.setState({
                imgURL: inputVal,
            });
            return;
        }
        this.updateImgURLByURL("");
    }
    protected updateImgURLByURL(url: string = "") {
        if (url !== this.state.imgURL) {
            if (typeof this.props.onChange === "function") {
                this.props.onChange(url);
            }
        }
    }
}
